package com.eastfair.venuebooking.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.venuebooking.dao.ExhibitionCustomerMapper;
import com.eastfair.venuebooking.dto.BusinessOpportunityDTO;
import com.eastfair.venuebooking.dto.ExhibitionCustomerDTO;
import com.eastfair.venuebooking.entity.CustomerMain;
import com.eastfair.venuebooking.entity.ExhibitionCustomer;
import com.eastfair.venuebooking.entity.SaleClue;
import com.eastfair.venuebooking.enumeration.ExhibitionCustomerBusinessTypeEnum;
import com.eastfair.venuebooking.enums.CustomerIdentityEnum;
import com.eastfair.venuebooking.exceptioncode.VenueBookingExceptionCode;
import com.eastfair.venuebooking.service.BusinessOpportunityService;
import com.eastfair.venuebooking.service.CustomerMainService;
import com.eastfair.venuebooking.service.ExhibitionCustomerService;
import com.eastfair.venuebooking.service.SaleClueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 展会客户关系
 * </p>
 *
 * @author dqq
 * @date 2023-04-03
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ExhibitionCustomerServiceImpl extends SuperServiceImpl<ExhibitionCustomerMapper, ExhibitionCustomer> implements ExhibitionCustomerService {

    @Resource
    private CustomerMainService customerMainService;

    @Resource
    private SaleClueService saleClueService;

    @Resource
    private BusinessOpportunityService businessOpportunityService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ExhibitionCustomer> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ExhibitionCustomer model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    @Override
    public List<ExhibitionCustomer> listExhibitionCustomer(ExhibitionCustomerDTO query) {
        QueryWrapper<ExhibitionCustomer> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(ExhibitionCustomer::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(query.getExhibitionId() != null, ExhibitionCustomer::getExhibitionId, query.getExhibitionId())
                .eq(query.getCustomerId() != null, ExhibitionCustomer::getCustomerId, query.getCustomerId())
                .eq(StrUtil.isNotBlank(query.getCustomerIdentity()), ExhibitionCustomer::getCustomerIdentity, query.getCustomerIdentity())
                .eq(query.getBusinessId() != null, ExhibitionCustomer::getBusinessId, query.getBusinessId())
                .eq(query.getBusinessType() != null, ExhibitionCustomer::getBusinessType, query.getBusinessType())
        ;
        return list(queryWrapper);
    }

    @Override
    public List<ExhibitionCustomer> listByExhibitionIdAndCustomerId(Long exhibitionId, Long customerId, String customerIdentity) {
        log.info("listExhibitionCustomer - 查询展会与客户关系, exhibitionId={}, customerId={}, customerIdentity={}", exhibitionId, customerId, customerIdentity);
        ExhibitionCustomerDTO query = new ExhibitionCustomerDTO();
        query.setExhibitionId(exhibitionId);
        query.setCustomerId(customerId);
        query.setCustomerIdentity(customerIdentity);
        return listExhibitionCustomer(query);
    }

    @Override
    public List<ExhibitionCustomer> listByBusinessId(Long businessId, ExhibitionCustomerBusinessTypeEnum businessType) {
        ExhibitionCustomerDTO query = new ExhibitionCustomerDTO();
        query.setBusinessId(businessId);
        query.setBusinessType(businessType);
        return listExhibitionCustomer(query);
    }

    @Override
    public List<ExhibitionCustomer> listByExhibitionIdAndBusinessId(Long exhibitionId, Long businessId, ExhibitionCustomerBusinessTypeEnum businessType) {
        ExhibitionCustomerDTO query = new ExhibitionCustomerDTO();
        query.setBusinessId(businessId);
        query.setBusinessType(businessType);
        query.setExhibitionId(exhibitionId);
        return listExhibitionCustomer(query);
    }

    @Override
    public ExhibitionCustomer getSponsorByExhibitionId(Long exhibitionId) {
        log.info("getSponsorByExhibitionId - 展会ID获取展会的主办客户关系, exhibitionId={}", exhibitionId);
        ExhibitionCustomerDTO query = new ExhibitionCustomerDTO();
        query.setExhibitionId(exhibitionId);
        query.setCustomerIdentity(CustomerIdentityEnum.SPONSOR.getCode());
        List<ExhibitionCustomer> list = listExhibitionCustomer(query);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveForSaleClueOrBusinessOpportunity(ExhibitionCustomerDTO exhibitionCustomerDTO) {
        log.info("saveForSaleClueOrBusinessOpportunity - 为线索或商机保存展会客户关系, exhibitionCustomerDTO={}", exhibitionCustomerDTO);
        // 删除该数据源产生的展会客户关系
        if (exhibitionCustomerDTO.getBusinessId() != null && exhibitionCustomerDTO.getBusinessType() != null) {
            removeByBusinessIdAndRelatedBusinessId(exhibitionCustomerDTO.getBusinessId(), exhibitionCustomerDTO.getBusinessType());
        }
        // 如果保存的是主办客户展会关系，则看当前展会是否已经有主办了
        if (CustomerIdentityEnum.SPONSOR.eq(exhibitionCustomerDTO.getCustomerIdentity())) {
            ExhibitionCustomer existSponsor = getSponsorByExhibitionId(exhibitionCustomerDTO.getExhibitionId());
            if (existSponsor != null) {
                throw BizException.wrap(VenueBookingExceptionCode.EX_SPONSOR_HAS_EXIST.getCode(), "该展会已存在主办方");
            }
        }
        if (CustomerIdentityEnum.UNDERTAKER.eq(exhibitionCustomerDTO.getCustomerIdentity())) {
            List<ExhibitionCustomer> existUnderTakers = listByExhibitionIdAndCustomerId(exhibitionCustomerDTO.getExhibitionId(), exhibitionCustomerDTO.getCustomerId(), exhibitionCustomerDTO.getCustomerIdentity());
            if (existUnderTakers != null && !existUnderTakers.isEmpty()) {
                return false;
            }
        }
        // 保存展会客户关系
        return saveExhibitionCustomer(exhibitionCustomerDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveExhibitionCustomer(ExhibitionCustomerDTO exhibitionCustomerDTO) {
        log.info("saveExhibitionCustomer - 保存展会客户关系, exhibitionCustomerDTO={}", exhibitionCustomerDTO);
        ExhibitionCustomer exhibitionCustomer = BeanUtil.toBean(exhibitionCustomerDTO, ExhibitionCustomer.class);
        CustomerMain customerMain = customerMainService.getById(exhibitionCustomerDTO.getCustomerId());
        if(Objects.nonNull(customerMain)){
            exhibitionCustomer.setCustomerName(exhibitionCustomer.getCustomerName());
        }
        return save(exhibitionCustomer);
    }

    @Override
    public void removeByExhibitionIdOfSelf(Long exhibitionId) {
        update(new UpdateWrapper<ExhibitionCustomer>().lambda()
                .eq(ExhibitionCustomer::getExhibitionId,exhibitionId)
                .eq(ExhibitionCustomer::getIsDeleted,BusinessConstant.DELETE_NO)
                .eq(ExhibitionCustomer::getBusinessType, ExhibitionCustomerBusinessTypeEnum.EXHIBITION)
                .set(ExhibitionCustomer::getIsDeleted,BusinessConstant.DELETE_YES));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByBusinessId(Long businessId, ExhibitionCustomerBusinessTypeEnum businessType) {
        log.info("removeByBusinessId - 来源ID删除展会客户关系, businessId={}, businessType={}", businessId, businessType);
        List<ExhibitionCustomer> list = listByBusinessId(businessId, businessType);
        if (list == null || list.isEmpty()) {
            return true;
        }
        List<Long> ids = list
                .stream()
                .map(SuperEntity::getId)
                .collect(Collectors.toList());
        return removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeBatchByBusinessIds(List<Long> businessIds, ExhibitionCustomerBusinessTypeEnum businessType) {
        if (businessIds == null || businessIds.isEmpty()) {
            return true;
        }
        businessIds.forEach(businessId -> removeByBusinessId(businessId, businessType));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByExhibitionIdAndBusinessId(Long exhibitionId, Long businessId, ExhibitionCustomerBusinessTypeEnum businessType) {
        log.info("removeByExhibitionIdAndBusinessId - 展会ID，来源业务ID查询展会客户关系, exhibitionId={}, businessId={}, businessType={}", exhibitionId, businessId, businessId);
        List<ExhibitionCustomer> list = listByExhibitionIdAndBusinessId(exhibitionId, businessId, businessType);
        if (list == null || list.isEmpty()) {
            return true;
        }
        List<Long> ids = list
                .stream()
                .map(SuperEntity::getId)
                .collect(Collectors.toList());
        return removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByBusinessIdAndRelatedBusinessId(Long businessId, ExhibitionCustomerBusinessTypeEnum businessType) {
        removeByBusinessId(businessId, businessType);
        if (ExhibitionCustomerBusinessTypeEnum.SALE_CLUE.eq(businessType)) {
            // 查询关联的商机, 删除商机产生的展会客户关系
            BusinessOpportunityDTO businessOpportunity = businessOpportunityService.getBySaleClueId(businessId);
            if (businessOpportunity != null) {
                removeByBusinessId(businessOpportunity.getId(), ExhibitionCustomerBusinessTypeEnum.BUSINESS_OPPORTUNITY);
            }
        }
        if (ExhibitionCustomerBusinessTypeEnum.BUSINESS_OPPORTUNITY.eq(businessType)) {
            // 查询关联的线索，删除线索产生的展会客户关系
            SaleClue saleClue = saleClueService.getByBusinessOpportunityId(businessId);
            if (saleClue != null) {
                removeByBusinessId(saleClue.getId(), ExhibitionCustomerBusinessTypeEnum.SALE_CLUE);
            }
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByBusinessIdAndSaveByRelatedBusinessId(Long businessId, ExhibitionCustomerBusinessTypeEnum businessType) {
        removeByBusinessIdAndRelatedBusinessId(businessId, businessType);
        if (ExhibitionCustomerBusinessTypeEnum.SALE_CLUE.eq(businessType)) {
            // 查询关联的商机, 保存商机产生的展会客户关系
            BusinessOpportunityDTO businessOpportunity = businessOpportunityService.getBySaleClueId(businessId);
            if (businessOpportunity != null) {
                businessOpportunityService.saveExhibitionCustomer(businessOpportunity);
            }
        }
        if (ExhibitionCustomerBusinessTypeEnum.BUSINESS_OPPORTUNITY.eq(businessType)) {
            // 查询关联的线索，保存线索产生的展会客户关系
            SaleClue saleClue = saleClueService.getByBusinessOpportunityId(businessId);
            if (saleClue != null) {
                saleClueService.saveExhibitionCustomer(saleClue);
            }
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByBusinessIdsAndSaveByRelatedBusinessIds(List<Long> businessIds, ExhibitionCustomerBusinessTypeEnum businessType) {
        if (businessIds == null || businessIds.isEmpty()) {
            return true;
        }
        businessIds.forEach(businessId -> removeByBusinessIdAndSaveByRelatedBusinessId(businessId, businessType));
        return true;
    }
}
